package com.guimin.common.interceptor;

import com.aliyuncs.exceptions.ClientException;
import com.guimin.common.util.exception.BaseException;
import com.guimin.common.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

/**
 * 全局异常处理器
 * @author hzy
 */
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    /**
     * 服务器异常
     * @param e 异常类
     * @return 结果集
     */
    //@ExceptionHandler(Exception.class)
    public R<String> globalException(Exception e){
        log.error("【服务器异常】"  + e.getMessage());
        e.printStackTrace();
        return R.fail("500","服务器错误",null);
    }
    /**
     * 运行时异常
     * @param e 异常类
     * @return 结果集
     */
    //@ExceptionHandler(RuntimeException.class)
    public R<String> globalRuntimeException(RuntimeException e){
        log.warn("运行时异常-异常消息："  + e.getMessage());
        return R.fail("500",e.getMessage(),null);
    }
    /**
     * 基本异常
     * @param e 异常类
     * @return 结果集
     */
    @ExceptionHandler(BaseException.class)
    public R<String> globalBaseMessageException(BaseException e){
        log.debug("错误消息："  + e.getMessage());
        return R.fail(e.getMessage());
    }
    /**
     * 客户端异常
     * @param e 异常类
     * @return 结果集
     */
    @ExceptionHandler(ClientException.class)
    public R<String> globalBaseMessageException(ClientException e){
        log.info("错误消息："  + e.getMessage());
        return R.fail("短信暂时无法发送");
    }
    /**
     * 校验异常
     * @param e 异常类
     * @return 结果集
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<List<String>> exceptionHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult=e.getBindingResult();
        //获取校验报告
        List<String> msgList=new ArrayList<>();
        StringBuilder stringBuilder=new StringBuilder();
        for(FieldError fieldError:bindingResult.getFieldErrors()){
            log.debug("【校验内容】: {}={};【校验报告】:{}",fieldError.getField(),fieldError.getRejectedValue(),fieldError.getDefaultMessage());
            //封装校验报告
            stringBuilder.append(fieldError.getDefaultMessage()).append(";");
            msgList.add(fieldError.getField()+fieldError.getDefaultMessage());
        }
        //返回结果
        return R.fail(stringBuilder.toString(),msgList);
    }
    /**
     * 校验异常
     * @param e 异常类
     * @return 结果集
     */
    @ExceptionHandler({ConstraintViolationException.class, MissingServletRequestParameterException.class})
    public R<String> constraintViolationException(Exception e) {
        //返回结果
        return R.fail(e.getMessage());
    }
    /**ConstraintViolationException
     * 无权限访问
     * @param e 异常类
     * @return 结果集
     */
    @ExceptionHandler(NoSuchBeanDefinitionException.class)
    public R<String> unauthorizedHandler(NoSuchBeanDefinitionException e) {
        //返回结果
        return R.fail("401","无访问权限",e.getMessage());
    }
    /**
     * Http消息不可读异常
     * @param e 异常类
     * @return 结果集
     */
//    @ExceptionHandler(HttpMessageNotReadableException.class)
    public R<String> httpMessageNotReadableException(HttpMessageNotReadableException e) {
        //返回结果
        return R.fail("400","请求数据格式错误",e.getMessage());
    }
    @ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
    public R<String> httpMediaTypeNotSupportedException(org.springframework.web.HttpMediaTypeNotSupportedException e){
        return R.fail("请求格式错误",e.getMessage());
    }



}